<script setup lang="ts">
import { computed, onMounted, reactive, ref } from "vue";
import { storeToRefs } from "pinia";
import { useUserState } from "../store";
import { ElMessage, FormInstance } from "element-plus";
import { routeList } from "../config/route/routes";
import router from "../config/route";
import { userLoginUsingPost, userLogoutUsingPost } from "../servers/user/api/userController";

const { user } = storeToRefs(useUserState());
const { setUserState, matchUserRole } = useUserState();

// 渲染路由 使用计算属性，动态计算
const visibleRoutes = computed(() => {
  return routeList.filter((item) => {
    // 检验当前用户是否符合对应路由权限
    return matchUserRole(item.meta?.access as string);
  });
});

// 选择菜单数组
const selectKeys = ref("");
// 选择菜单
const handleSelect = (index: string) => {
  router.push({ path: index });
};

// 路由跳转之后执行
router.afterEach((to) => {
  selectKeys.value = to.path;
});

// 未登录弹出框
const loginVisible = ref(false);
const initUser = {
  userAccount: "",
  userPassword: "",
};

// 点击未登录按钮显示
const handleClickLogin = async () => {
  loginVisible.value = true;
};

// 表单ref对象
const loginUserForm = reactive({ ...initUser });
const loginUserFormRef = ref<FormInstance>();

// 登录校验规则
const loginFormRules = {
  userAccount: [{ required: true, message: "请输入账号", trigger: "blur" }],
  userPassword: [{ required: true, message: "请输入密码", trigger: "blur" }],
};

// 点击登录
const onLogin = async () => {
  // 登录
  const { data } = await userLoginUsingPost({ ...loginUserForm });
  console.log(data.data);
  // 保存用户态
  if (data.code === 200) {
    setUserState(data.data!);
    ElMessage.success("用户成功登录");
    // 关闭model框
    loginVisible.value = false;
    // 登录成功清除表单
    reSet();
  } else {
    ElMessage.error("登录失败：" + data.message);
  }
};

// 取消
const onCancel = async () => {
  loginVisible.value = false;
};
// 重置
const reSet = () => {
  // 清空表单数据
  loginUserFormRef.value?.resetFields();
};

// 退出登录
// 弹出框
const logoutVisible = ref(false);
const onLogout = async () => {
  // 隐藏退出登录按钮
  logoutVisible.value = false;
  // 切换为退出登录接口
  const { data } = await userLogoutUsingPost();
  if (data.code === 200) {
    ElMessage.info("用户退出登录");
  } else {
    new Error(data.message);
    ElMessage.error(data.message ?? "登录出错");
  }
  // 清除用户登录态
  setUserState({});
  // 刷新并跳转到主页
  location.reload();
  router.push("/");
};

onMounted(() => {
  // 页面加载时，获取用户登录信息，存入登录用户
  // 因为在路由中写了，所以这里就不用写了
  // getLoginUserState();
});
</script>
<template>
  <div class="menu-header">
    <el-row :gutter="20" class="header-row">
      <el-col :span="2" class="logo-col">
        <img class="logo" src="../assets/logo.png" alt="Element logo" />
        <el-text class="title" type="info" size="large">znxs-OJ</el-text>
      </el-col>
      <el-col :span="20" class="menu-col">
        <el-menu
          :default-active="selectKeys"
          class="el-menu-demo"
          mode="horizontal"
          @select="handleSelect"
          :router="true"
        >
          <el-menu-item
            :index="item.path"
            v-for="item in visibleRoutes"
            :key="item.path"
          >
            {{ item.name }}
          </el-menu-item>
        </el-menu>
      </el-col>
      <el-col :span="2" class="user-col">
        <div v-if="user.userName" class="user-info">
          <el-popover
            :show-arrow="false"
            :visible="logoutVisible"
            placement="top"
            class="popover"
          >
            <div class="popover-content">
              <el-button @click="onLogout">退出账号</el-button>
              <el-button @click="logoutVisible = false">取消</el-button>
            </div>
            <template #reference>
              <div class="user-reference" @click="logoutVisible = true">
                <el-avatar
                  :size="40"
                  src="https://img.znxs.vip/znxs/avatar_%E7%A5%9E%E9%87%8C.jpg"
                />
                <el-text class="username" type="info" size="large"
                  >{{ user.userName }}
                </el-text>
              </div>
            </template>
          </el-popover>
        </div>
        <div v-else class="login-button">
          <el-button @click="handleClickLogin">未登录</el-button>
          <el-dialog
            title="登录"
            width="600px"
            v-model="loginVisible"
            @close="onCancel"
          >
            <el-form
              ref="loginUserFormRef"
              :model="loginUserForm"
              label-width="80px"
              :rules="loginFormRules"
            >
              <el-form-item label="帐号" prop="userAccount">
                <el-input
                  placeholder="请输入账号"
                  v-model="loginUserForm.userAccount"
                ></el-input>
              </el-form-item>
              <el-form-item label="密码" prop="userPassword">
                <el-input
                  type="password"
                  placeholder="请输入密码"
                  v-model="loginUserForm.userPassword"
                  @keyup.enter="onLogin"
                ></el-input>
              </el-form-item>
              <el-form-item>
                <div class="dialog-footer">
                  <el-button size="small" @click="reSet()">重置</el-button>
                  <el-button size="small" @click="onCancel">取消</el-button>
                  <el-button size="small" type="primary" @click="onLogin"
                    >确定
                  </el-button>
                </div>
              </el-form-item>
            </el-form>
          </el-dialog>
        </div>
      </el-col>
    </el-row>
  </div>
</template>

<style scoped>
.menu-header {
  height: 60px;
  margin-bottom: 10px;
  box-shadow: 0px 1px 1px #888888;
  width: 100%;
  user-select: none;
}

.header-row {
  display: flex;
  flex-wrap: nowrap;
  width: 100%;
}

.logo-col {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.logo {
  width: 40px;
  margin-left: 30px;
}

.title {
  margin-left: 10px;
  user-select: none;
}

.menu-col {
  flex-grow: 1;
}

.user-col {
  display: flex;
  align-items: center;
  flex-shrink: 0;
}

.user-info {
  display: flex;
  align-items: center;
}

.popover-content {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
}

.popover-content .el-button {
  margin: 5px 0px 0px 0px;
}

.user-reference {
  display: flex;
  align-items: center;
}

.username {
  margin-left: 20px;
  user-select: none;
}

.dialog-footer {
  display: flex;
  justify-content: space-between;
}
</style>
